package cn.itcast.nio.c2;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

import static cn.itcast.nio.c1.ByteBufferUtil.debugAll;


/**
 * AIO(异步IO)演示
 */
@Slf4j
public class AioFileChannel {
    public static void main(String[] args) throws IOException {
        try (AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get("data.txt"), StandardOpenOption.READ)) {
            // 参数1 ByteBuffer
            // 参数2 读取的起始位置
            // 参数3 附件
            // 参数4 回调对象 CompletionHandler
            ByteBuffer buffer = ByteBuffer.allocate(16);
            log.debug("read begin...");

            channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                @Override // read 成功回调
                public void completed(Integer result, ByteBuffer attachment) { //result数量  attachment我们自己传递进去的附件
                    log.debug("read completed...{}", result);
                    attachment.flip();
                    debugAll(attachment);
                }
                @Override // read 失败回调
                public void failed(Throwable exc, ByteBuffer attachment) {
                    exc.printStackTrace();
                }
            });
            log.debug("read end...");   //看打印顺序就能知道是不是异步了 如果再read completed之前有出现read end 就肯定异步了
        } catch (IOException e) {
            e.printStackTrace();
        }
        //上面的channel.read代码是个守护线程在执行,所以如果主线程结束了 守护线程自然就死了 就可能完全读取不到数据
        // 所以这里得阻塞一下让守护线程处理完回调
        System.in.read();
    }
}
